﻿/********************************************************************************
** 作者： samfeng
** 创始时间：2012-7-15
** 描述：
** 功能：转换工具类
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Data;
using System.Text;
using System.Xml;
using Newtonsoft.Json;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace DBA.Common
{
    public class ConvertHelper
    {
        public static T DataRowToObject<T>(DataRow dr)
        {
            try
            {
                if (dr == null)
                {
                    return default(T);
                }
                return ReflectorHelper.GetObject<T>(ReflectorHelper.GetKeyValueListFromDataRow(dr));
            }
            catch
            {
                return default(T);
            }
        }

        public static List<T> DataTableToList<T>(DataTable dt)
        {
            List<T> list = new List<T>();
            foreach (DataRow row in dt.Rows)
            {
                list.Add(DataRowToObject<T>(row));
            }
            dt.Dispose();
            return list;
        }

        public static byte ToByte(object obj)
        {
            return ToByte(obj, 0);
        }

        public static byte ToByte(object obj, byte _default)
        {
            try
            {
                return Convert.ToByte(obj);
            }
            catch
            {
                return _default;
            }
        }

        public static double ToDouble(object input)
        {
            return ToDouble(input, 0.0);
        }

        public static double ToDouble(object input, double _default)
        {
            try
            {
                return Convert.ToDouble(input);
            }
            catch
            {
                return _default;
            }
        }

        public static short ToInt16(object obj)
        {
            return ToInt16(obj, 0);
        }

        public static short ToInt16(object obj, short _default)
        {
            try
            {
                return Convert.ToInt16(ToDouble(obj));
            }
            catch
            {
                return _default;
            }
        }

        public static int ToInt32(object input)
        {
            return ToInt32(input, 0);
        }

        public static int ToInt32(object input, int _default)
        {
            try
            {
                return Convert.ToInt32(ToDouble(input));
            }
            catch
            {
                return _default;
            }
        }

        public static long ToInt64(object input)
        {
            return ToInt64(input, 0L);
        }

        public static long ToInt64(object input, long _default)
        {
            try
            {
                return Convert.ToInt64(ToDouble(input));
            }
            catch
            {
                return _default;
            }
        }

        public static float ToSingle(object input)
        {
            return ToSingle(input, 0f);
        }

        public static float ToSingle(object input, float _default)
        {
            try
            {
                return Convert.ToSingle(input);
            }
            catch
            {
                return _default;
            }
        }

        #region 转换Int32
        /// <summary>
        /// 强制转换为整数,转换失败则返回默认值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="_default"></param>
        /// <returns></returns>
        public static int ToInt(object obj, int _default)
        {
            try
            {
                return System.Convert.ToInt32(obj);
            }
            catch
            {
                return _default;
            }
        }
        /// <summary>
        /// 强制转换为整数,转换失败则返回0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static int ToInt(object obj)
        {
            return ToInt(obj, 0);
        }
        #endregion

        #region 转换Int64
        /// <summary>
        /// 强制转换为Int64,转换失败则返回默认值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="_default"></param>
        /// <returns></returns>
        public static long ToLong(object obj, long _default)
        {
            try
            {
                return System.Convert.ToInt64(obj);
            }
            catch
            {
                return _default;
            }
        }
        /// <summary>
        /// 强制转换为Int64,转换失败则返回0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static long ToLong(object obj)
        {
            return ToLong(obj, 0L);
        }
        #endregion

        #region 转换Decimal
        /// <summary>
        /// 强制转换为Decimal类型,转换失败则返回默认值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="_default"></param>
        /// <returns></returns>
        public static decimal ToDecimal(object obj, decimal _default)
        {
            try
            {
                return System.Convert.ToDecimal(obj);
            }
            catch
            {
                return _default;
            }
        }
        /// <summary>
        /// 强制转换为Decimal类型,转换失败则返回0
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static decimal ToDecimal(object obj)
        {
            return ToDecimal(obj, 0M);
        }
        #endregion


        #region 转换时间
        /// <summary>
        /// 强制转换为时间类型,转换失败则返回默认值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="_default"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(object obj, DateTime _default)
        {
            try
            {
                return System.Convert.ToDateTime(obj);
            }
            catch
            {
                return _default;
            }
        }
        /// <summary>
        /// 强制转换为时间类型,转换失败则返回当前时间
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(object obj)
        {
            return ToDateTime(obj, DateTime.Now);
        }
        /// <summary>
        /// 如果非时间格式，那么转换为1797-01-01年
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static DateTime ToNullDateTime(object obj)
        {
            return ToDateTime(obj, ToDateTime("1797-01-01"));
        }

        
        #endregion

        #region 转换Boolean
        /// <summary>
        /// 强制转换为Boolean对象,转换失败返回默认值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="_default"></param>
        /// <returns></returns>
        public static Boolean ToBoolean(object obj, Boolean _default)
        {
            try
            {
                return System.Convert.ToBoolean(obj);
            }
            catch
            {
                return _default;
            }
        }
        /// <summary>
        /// 强制转换为Boolean对象,转换失败返回False
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Boolean ToBoolean(object obj)
        {
            return ToBoolean(obj, false);
        }
        #endregion

        #region 转换Guid
        /// <summary>
        /// 强制转换为Guid类型,转换失败返回默认值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="_default"></param>
        /// <returns></returns>
        public static Guid ToGuid(object obj, Guid _default)
        {
            try
            {
                return new Guid(obj.ToString());
            }
            catch
            {
                return _default;
            }
        }
        /// <summary>
        /// 强制转换为Guid类型,转换失败返回空Guid
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Guid ToGuid(object obj)
        {
            return ToGuid(obj, new Guid());
        }
        #endregion

        #region XML转换

        #region XML转换成OBJECT
        public static List<T> XmlToList<T>(string filename, Xml.ObjectAttrbuteSaveType saveType) where T: new()
        {
            string name = typeof(T).Name;
            string path = "/" + name + "List/" + name;
            return XmlToList<T>(filename, path, saveType);
        }

        public static List<T> XmlToList<T>(XmlNodeList noList, Xml.ObjectAttrbuteSaveType saveType) where T: new()
        {
            List<T> list = new List<T>();
            foreach (XmlNode node in noList)
            {
                list.Add(XmlToObject<T>(node, saveType));
            }
            return list;
        }

        public static List<T> XmlToList<T>(string filename, string path, Xml.ObjectAttrbuteSaveType saveType) where T: new()
        {
            XmlNodeList xmlNodeList = new Xml(filename).GetXmlNodeList(path);
            if (xmlNodeList == null)
            {
                throw new Exception("未能加载指定路径的节点!");
            }
            return XmlToList<T>(xmlNodeList, saveType);
        }

        #endregion

        #region XML转换成OBJECT
        public static T XmlToObject<T>(string filename, Xml.ObjectAttrbuteSaveType saveType) where T : new()
        {
            string path = "/" + typeof(T).Name;
            return XmlToObject<T>(filename, path, saveType);
        }

        public static T XmlToObject<T>(XmlNode no, Xml.ObjectAttrbuteSaveType saveType) where T : new()
        {
            try
            {
                return ReflectorHelper.GetObject<T>(ReflectorHelper.GetKeyValueListFromXml(no, saveType));
            }
            catch
            {
                return default(T);
            }
        }

        public static T XmlToObject<T>(string filename, string path, Xml.ObjectAttrbuteSaveType saveType) where T : new()
        {
            XmlNode xmlNode = new Xml(filename).GetXmlNode(path);
            if (xmlNode == null)
            {
                throw new Exception("未能加载对应的节点!");
            }
            return XmlToObject<T>(xmlNode, saveType);
        }
        #endregion

        #endregion

        #region json转换
        /// <summary>
        /// 将JSON转换成DataTable
        /// </summary>
        /// <param name="jsonStr">JSON字符串</param>
        /// <returns></returns>
        public static DataTable JsonToDataTable(string jsonStr)
        {
            return JsonConvert.DeserializeObject<DataTable>(jsonStr);
        }

        /// <summary>
        /// 根据传递来的DataTable为模板，将JSON转换成DataTable(暂时未实现 )
        /// </summary>
        /// <param name="jsonStr"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DataTable JsonToDataTable(string jsonStr, DataTable dt)
        {
            throw new NotImplementedException();
        }
        #endregion

        #region 转换前台的对象为字符串的显示
        public static string ToEvalDateTime(object obj,string formatString)
        {
            DateTime reValue = ToNullDateTime(obj);

            return reValue.CompareTo(ToDateTime("1797-01-01"))==0?String.Empty:reValue.ToString(formatString);
        }
        public static string ToEvalBoolean(object obj, string trueValue, string falseValue)
        {
            return ToBoolean(obj) ? trueValue : falseValue;
        }
        public static string ToEvelTinyInt(object obj, params string[] values)
        {
            return values[ConvertHelper.ToInt32(obj)];
        }
        #endregion

        #region 将数据库中的数据类型转换到应用程序中的类型
        public static DbType ConvertStringToSqlserverDbType(string dataType)
        {
            DbType dbType = DbType.String;
            switch (dataType)
            {
                case "int identity":
                    dbType = DbType.Int32;
                    break;
                case "bigint identity":
                    dbType = DbType.Int64;
                    break;
                case "uniqueidentifier":
                    dbType = DbType.Guid;
                    break;
                case "numeric":
                    dbType = DbType.Decimal;
                    break;
                case "date":
                    dbType = DbType.Date;
                    break;
                case "int":
                    dbType = DbType.Int32;
                    break;
                case "smallint":
                    dbType = DbType.Int16;
                    break;
                case "nvarchar":
                    dbType = DbType.String;
                    break;
                case "varchar":
                    dbType = DbType.String;
                    break;
                case "float":
                    dbType = DbType.Double;
                    break;
                case "money":
                    dbType = DbType.Decimal;
                    break;
                case "datetime":
                    dbType = DbType.DateTime;
                    break;
                case "smalldatetime":
                    dbType = DbType.DateTime;
                    break;
                case "decimal":
                    dbType = DbType.Decimal;
                    break;
                case "bigint":
                    dbType = DbType.Int64;
                    break;
                case "char":
                    dbType = DbType.String;
                    break;
                case "bit":
                    dbType = DbType.Boolean;
                    break;
                case "smallmoney":
                    dbType = DbType.Decimal;
                    break;
                case "text":
                    dbType = DbType.String;
                    break;
                case "ntext":
                    dbType = DbType.String;
                    break;
                case "nchar":
                    dbType = DbType.StringFixedLength;
                    break;
                case "image":
                    dbType = DbType.Binary;
                    break;
                case "varbinary":
                    dbType = DbType.Binary;
                    break;
                case "real":
                    dbType = DbType.Single;
                    break;
                case "tinyint":
                    dbType = DbType.Byte;
                    break;
                case "sql_variant":
                    dbType = DbType.Object;
                    break;
                case "binary":
                    dbType = DbType.Binary;
                    break;
                case "timestamp":
                    dbType = DbType.Binary;
                    break;
                case "xml":
                    dbType = DbType.Xml;
                    break;
            }
            return dbType;
        }
        /// <summary>
        /// 将SQLSERVER的数据类型转换成C#中的数据类型
        /// </summary>
        /// <param name="dataType"></param>
        /// <returns></returns>
        public static string ConvertSqlServerDbTypeToCS(string dataType)
        {
            switch (dataType)
            {
                case "int identity":
                    return "int";

                case "bigint identity":
                    return "long";

                case "uniqueidentifier":
                    return "Guid";

                case "int":
                    return "int";

                case "smallint":
                    return "int";

                case "nvarchar":
                    return "string";

                case "varchar":
                    return "string";

                case "float":
                    return "double";

                case "money":
                    return "decimal";

                case "datetime":
                    return "DateTime";

                case "smalldatetime":
                    return "DateTime";

                case "decimal":
                    return "decimal";

                case "bigint":
                    return "long";

                case "char":
                    return "string";

                case "bit":
                    return "bool";

                case "smallmoney":
                    return "decimal";

                case "text":
                    return "string";

                case "ntext":
                    return "string";

                case "nchar":
                    return "string";

                case "image":
                    return "byte[]";

                case "varbinary":
                    return "byte[]";

                case "real":
                    return "float";

                case "tinyint":
                    return "byte";

                case "sql_variant":
                    return "object";

                case "binary":
                    return "object";
            }
            return "";
        }

        /// <summary>
        /// 将SQLSERVER中的数据类型转换成NHibernate中的数据类型
        /// </summary>
        /// <param name="dataType"></param>
        /// <returns></returns>
        public static string ConvertSqlServerDbTypeToNHbm(string dataType)
        {
            switch (dataType)
            {
                case "int identity":
                    return "Int32";

                case "bigint identity":
                    return "Int32";

                case "uniqueidentifier":
                    return "Guid";

                case "int":
                    return "Int32";

                case "smallint":
                    return "Int32";

                case "nvarchar":
                    return "String";

                case "varchar":
                    return "String";

                case "float":
                    return "Double";

                case "money":
                    return "Decimal";

                case "datetime":
                    return "DateTime";

                case "smalldatetime":
                    return "DateTime";

                case "decimal":
                    return "Decimal";

                case "bigint":
                    return "Int32";

                case "char":
                    return "String";

                case "bit":
                    return "Boolean";

                case "smallmoney":
                    return "Decimal";

                case "text":
                    return "String";

                case "ntext":
                    return "String";

                case "nchar":
                    return "String";

                case "image":
                    return "Byte[]";

                case "varbinary":
                    return "Byte[]";

                case "real":
                    return "Single";

                case "tinyint":
                    return "Byte";

                case "sql_variant":
                    return "Object";

                case "binary":
                    return "Object";
            }
            return "";
        }
        #endregion



        /// <summary>
        /// 根据传递的实体对象和控件集合，对控件集合中的控件进行自适配赋值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t">实体对象的实例</param>
        /// <param name="controls">页面的控件集合</param>
        public static void ModelToControl<T>(T t, ControlCollection controls) 
        {          
            foreach (Control item in controls)
            {
                //如果是TextBox的处理方式
                if (item is TextBox)
                {
                    TextBox tmpTextBox = item as TextBox;
                    PropertyInfo proInfo = t.GetType().GetProperties().FirstOrDefault(p => p.Name.ToUpper() == tmpTextBox.ID.Substring(tmpTextBox.ID.IndexOf('_') + 1).ToUpper());
                    if (!VerificationHelper.IsNullOrEmpty<PropertyInfo>(proInfo))
                    {
                        tmpTextBox.Text = proInfo.FastGetValue<T>(t).ToString();
                    }
                    else
                    {
                        tmpTextBox.Text = "";
                    }   
                }
                //如果控件是HtmlInputText
                if (item is HtmlInputText)
                {
                    HtmlInputText tmpInputText = item as HtmlInputText;
                    PropertyInfo proInfo = t.GetType().GetProperties().FirstOrDefault(p => p.Name.ToUpper() == tmpInputText.ID.Substring(tmpInputText.ID.IndexOf('_')+1).ToUpper());
                    if (!VerificationHelper.IsNullOrEmpty<PropertyInfo>(proInfo))
                    {
                        tmpInputText.Value = proInfo.FastGetValue<T>(t).ToString();
                    }
                    else
                    {
                        tmpInputText.Value = "";
                    } 
                }
                //如果控件是HtmlTextArea
                if (item is HtmlTextArea)
                {
                    HtmlTextArea tmpTextArea = item as HtmlTextArea;
                    PropertyInfo proInfo = t.GetType().GetProperties().FirstOrDefault(p => p.Name.ToUpper() == tmpTextArea.ID.Substring(tmpTextArea.ID.IndexOf('_')+1).ToUpper());
                    if (!VerificationHelper.IsNullOrEmpty<PropertyInfo>(proInfo))
                    {
                        tmpTextArea.Value = proInfo.FastGetValue<T>(t).ToString();
                    }
                    else
                    {
                        tmpTextArea.Value = "";
                    }
                }
                //如果控件是下拉框
                if (item is DropDownList)
                {
                    DropDownList tmpDropDownList = item as DropDownList;
                    PropertyInfo proInfo = t.GetType().GetProperties().FirstOrDefault(p => p.Name.ToUpper() == tmpDropDownList.ID.Substring(tmpDropDownList.ID.IndexOf('_') + 1).ToUpper());
                    if (!VerificationHelper.IsNullOrEmpty<PropertyInfo>(proInfo))
                    {
                        ListItem li = tmpDropDownList.Items.FindByValue(proInfo.FastGetValue<T>(t).ToString());
                        if (!VerificationHelper.IsNullOrEmpty<ListItem>(li))
                        {
                            tmpDropDownList.ClearSelection();
                            li.Selected = true;
                        }
                    }
                    else
                    {
                        tmpDropDownList.ClearSelection();
                        tmpDropDownList.Items[0].Selected = true;
                    }
                }
            }
        }

        /// <summary>
        /// 根据传递来的控件集合进行比较，来得到一个实体对象
        /// </summary>
        /// <typeparam name="T">实体对象</typeparam>
        /// <param name="controls"></param>
        /// <returns></returns>
        public static T ControlToModel<T>(ControlCollection controls) 
        {
            T member = ReflectorHelper.CreateInstance<T>();
            foreach (Control item in controls)
            {
                //如果ITEM是文本框
                if (item is TextBox)
                {
                    TextBox txtTmp = item as TextBox;
                    PropertyHelper.FindAndSetValueByName<T>(item.ID.Substring(item.ID.IndexOf('_')+1), member, txtTmp.Text, false);
                }
                if (item is HtmlInputText)
                {
                    HtmlInputText iptTmp = item as HtmlInputText;
                    PropertyHelper.FindAndSetValueByName<T>(item.ID.Substring(item.ID.IndexOf('_')+1), member, iptTmp.Value, false);
                }
                if (item is DropDownList)
                {
                    DropDownList ddlTmp = item as DropDownList;
                    PropertyHelper.FindAndSetValueByName<T>(item.ID.Substring(item.ID.IndexOf('_')+1), member, ddlTmp.SelectedValue, false);
                }
                if (item is HtmlTextArea)
                {
                    HtmlTextArea areaTmp = item as HtmlTextArea;
                    PropertyHelper.FindAndSetValueByName<T>(item.ID.Substring(item.ID.IndexOf('_')+1), member, areaTmp.Value, false);
                }
            }
            return member;
        }

        /// <summary>
        /// 将DataTable转换成IList的实体集合
        /// </summary>
        /// <typeparam name="T">实体</typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static IList<T> CommDataTableToList<T>(DataTable dt) where T : new()
        {
            // 定义集合
            IList<T> ts = new List<T>();

            // 获得此模型的类型
            Type type = typeof(T);

            string tempName = String.Empty;

            foreach (DataRow dr in dt.Rows)
            {
                T t = new T();

                // 获得此模型的公共属性
                PropertyInfo[] propertys = t.GetType().GetProperties();

                foreach (PropertyInfo pi in propertys)
                {
                    tempName = pi.Name;

                    // 检查DataTable是否包含此列
                    if (dt.Columns.Contains(tempName))
                    {
                        // 判断此属性是否有Setter
                        if (!pi.CanWrite) continue;

                        object value = dr[tempName];
                        if (value != DBNull.Value)
                            pi.SetValue(t, value, null);
                    }
                }

                ts.Add(t);
            }

            return ts;

        }


        /// <summary>
        /// 将Reader转换成IList(只对应目前的MODEL，因为MODEL里的名称是和数据库对应的)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static IList<T> DataReaderToList<T>(System.Data.IDataReader reader)
        {
            IList<T> lst = new List<T>();
            while (reader.Read())
            {
                //T RowInstance = Activator.CreateInstance<T>();
                //foreach (PropertyInfo Property in typeof(T).GetProperties())
                //{
                //    //OrmPropertyAttribute tmpOrmAttribute = AttributeHelper.GetAAttribute<OrmPropertyAttribute, T>(Property.Name);
                //    //foreach (BindingFieldAttribute FieldAttr in Property.GetCustomAttributes(typeof(BindingFieldAttribute), true))
                //    //{
                //    //}
                //    try
                //    {
                //        //取得当前数据库字段的顺序
                //        int Ordinal = reader.GetOrdinal(Property.Name);
                //        if (reader.GetValue(Ordinal) != DBNull.Value)
                //        {
                //            //将DataReader读取出来的数据填充到对象实体的属性里
                //            Property.FastSetValue<T>(RowInstance, Convert.ChangeType(reader.GetValue(Ordinal), Property.PropertyType));
                //        }
                //    }
                //    catch
                //    {
                        
                //    }
                //}
                //lst.Add(RowInstance);
                T item = DynamicBuilder<T>.CreateBuilder(reader).Build(reader);
                lst.Add(item);
            }
            return lst;
        }
    }
}
